/***********************************************************************************
Copy right:	    Coffee Tech.
Author:         jiaoyue
Date:           2019.8.29
Description:    nv组件接口
***********************************************************************************/

#ifndef NV_UTILS_H
#define NV_UTILS_H

#include <log_utils.h>
#include <unix_sock.h>
#include <nv_pub.h>
#include <list.h>
#include <cJSON.h>

#define NV_False   cJSON_False
#define NV_True    cJSON_True
#define NV_NULL    cJSON_NULL
#define NV_Number  cJSON_Number
#define NV_String  cJSON_String
#define NV_Array   cJSON_Array
#define NV_Object  cJSON_Object

/**
 * @brief NV节点结构体
 */
struct nv_obj
{
   int type;  //节点类型，取上方宏定义，同CJSON类型
   char *valuestring;  //nv值，不管什么类型，如果有值，都会存一份字符串放到这里
   int valueint;  //如果值是整形，自动存入此值中
   double valuedouble;  //如果值是浮点型，自动存入此值中
   char nv_name[MAX_NV_NAME_LEN];  //nv节点名字
};

/**
 * @brief nv节点链表
 */
struct nv_list
{
    struct nv_obj obj;
    struct list_head list;
};

/**
 * @brief 初始化参数子系统客户端组件
 * @param mod_name 子系统或模块名称
 * @return 0 -1
 */
int nv_client_init(const char *mod_name);

/**
 * @brief 从nv服务中获取原始json数据存入到val中
 * @param name 配置名称
 * @param val 接收值缓冲区
 * @param val_len 缓冲区大小，可以直接赋值 MAX_NV_VAL_LEN
 * @return 成功返回值引用，失败NULL
 */
char *nv_get_origin(const char *name, char *val, int val_len);

/**
 * @brief 获取单个参数nv_obj结构体
 * @param obj 传入参数，无需赋值
 * @param nv_name 配置名称
 * @return 失败NULL，成功返回传入的obj地址，可根据节点类型取合适的类型值使用
 */
struct nv_obj *nv_get_obj(struct nv_obj *obj, const char *nv_name);

/**
 * @brief 释放单个nv_obj中申请的内存，每次调用nv_get_obj后使用
 * @param obj 需要释放内存的节点指针
 */
void nv_obj_free(struct nv_obj *obj);

/**
 * @brief 原始json字符串解析成nv_obj链表
 * @param nv_head
 * @param json_str 原始json
 * @return 0 -1
 */
int nv_get_list_from_string(struct list_head *nv_head, const char *json_str);

/**
 * @brief 原始文件解析成链表
 * @param nv_head   链表头
 * @param file_name 文件名
 * @return 0 -1
 */
int nv_get_list_from_file(struct list_head *nv_head, const char *file_name);

/**
 * @brief 从NV服务中获取多个参数并解析到nv_obj链表中
 * @param nv_head 存储链表头部
 * @param nv_name 获取节点名称，可以为父节点
 * @return 0 -1
 */
int nv_get_list(struct list_head *nv_head, const char *nv_name);

/**
 * @brief 调用nv_get_list_from_string或者nv_get_list_obj后从链表中获取某个具体节点
 * @param nv_head 链表头
 * @param nv_name 节点名
 * @return 失败NULL，成功返回传入的obj地址
 */
struct nv_obj *nv_get_list_obj(struct list_head *nv_head, const char *nv_name);

/**
 * @brief 链表节点空间释放，每次调用nv_get_list_from_string或nv_get_list后都需要调用一次
 * @param 链表头
 */
void nv_list_free(struct list_head *nv_head);

/**
 * @brief 设置参数
 * @param set_cmd 设置命令
 * @return 0 -1
 */
int nv_set_obj(const char *set_cmd);

/**
 * @brief 删除参数
 * @param del_cmd 删除命令
 * @return 0 -1
 */
int nv_del_obj(const char *del_cmd);

enum NV3_TYPE
{
    NV3_RDONLY = 0,
    NV3_RDRW
};

#define NV_LOG_CLIENT "nvclient"

#endif  //NV_UTILS_H
